package com.nirvana.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Properties;

import com.nirvana.core.Validator;

public class NirvanaUtil {
	
	private static final long MILLI_SEC_PER_DAY = 24l*60l*60l*1000l;
	
	public static final char[] ILLIGAL_CHARS_FILE_NAME = {'/', '\\', ':', '*', '?', '>', '<', '|', ']', '['};
	
	public static Date incDate(Date baseDate, int incrementDays) {
		// TimeZone zone = TimeZone.getTimeZone("GMT+0");
		Calendar cal = Calendar.getInstance(); // (zone);
		cal.setTime(baseDate);
		cal.add(Calendar.DATE,incrementDays);
		return cal.getTime();
	}
	
	/**
	 * Parses the a string which is in given format into java.util.Date.<br/>
	 * Format can be for example MM/dd/yyyy (uses format given in SimpleDateFormat).<br/>
	 * Default format: <b>'yyyy-MM-dd'</b><br/>
	 * 
	 * @param date 
	 * @param format
	 * @return date, returns null if the date string is null.	  
	 */
	public static Date parse(String date, String format){
		if(date==null)
			return null;
		
		try {
			if (format == null)
				format = "yyyy-MM-dd";

			SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
			simpleDateFormat.setLenient(false);
			return simpleDateFormat.parse(date); //just for throwing the exception if it's an invalid date

		} catch (Exception e) {
			return null;
		}
	}
	
	/**
	 * formats the a date to the given format<br/>
	 * Format can be for example MM/dd/yyyy (uses format given in SimpleDateFormat).<br/>
	 * Default format: <b>'yyyy-MM-dd'</b><br/>
	 * 
	 * @param date 
	 * @param format
	 * @return date, returns null if the given date is null.	  
	 */
	public static String format(Date date, String format){
		if(date==null)
			return null;
		
		try {
			if (format == null)
				format = "yyyy-MM-dd";

			SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
			simpleDateFormat.setLenient(false);
			return simpleDateFormat.format(date); //just for throwing the exception if it's an invalid date

		} catch (Exception e) {
			return null;
		}
	}
	
	/**
	 * 
	 * @param date
	 * @param formatFrom
	 * @param formatTo
	 * @return
	 */
	public static String format(String date, String formatFrom, String formatTo){
		if(date==null)
			return null;
		try {
			return format(parse(date,formatFrom), formatTo);
		} catch (Exception e) {
			return null;
		}
	}
	
	public static Date getDateNoTime(Date date) {
		
		Date dateNoTime = null;
		if (date != null) {
			dateNoTime = parse(format(date, null), null);
		}
		return dateNoTime;
	}

	public static Date getDate(int year, int month, int day) {
		// TimeZone zone = TimeZone.getTimeZone("GMT+0");
		Calendar cal = Calendar.getInstance(); // (zone);
		cal.clear();
		cal.set(year,month,day);
		return cal.getTime();
	}

	public static Date getNow() {
		// TimeZone zone = TimeZone.getTimeZone("GMT+0");
		Calendar cal = Calendar.getInstance(); // (zone);
		return cal.getTime();
	}

	/**
	 * Today's date (without the time portion, thus as of midnight this morning).
	 */
	public static Date getToday() {
		return getToday(0);
	}

	/**
	 * Today's date plus or minus the given number of days (without the time
	 * portion, thus as of midnight of the specified morning). 0 means today. -1
	 * means yesterday. 1 means tomorrow.
	 */
	public static Date getToday(int incrementDays) {
		// TimeZone zone = TimeZone.getTimeZone("GMT+0");
		Calendar cal = Calendar.getInstance(); // (zone);
		cal.add(Calendar.DATE,incrementDays);
		clearTimePortion(cal);
		return cal.getTime();
	}

	private static void clearTimePortion(Calendar cal) {
		cal.set(Calendar.AM_PM,0);
		cal.set(Calendar.HOUR,0);
		cal.set(Calendar.MINUTE,0);
		cal.set(Calendar.SECOND,0);
		cal.set(Calendar.MILLISECOND,0);
	}
	

	public static void addAll(ArrayList list, Object[] array){
		for (int i = 0; i < array.length; i++) {
			list.add(array[i]);
		}
	}
	
	public static Properties convertStringToProperties(String data) {
		
		try {
			Properties properties = new Properties();
			ByteArrayInputStream inputStream = new ByteArrayInputStream(data.getBytes());
			//ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
			properties.load(inputStream);
			//properties= (Properties) objectInputStream.readObject();
			return properties;
		} catch (IOException e) {
			
			return null; 
		} 
	}
	
	public static String convertPropertiesToString(Properties properties) {
		try {
			ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
			ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
			properties.store(outputStream, null);
			//objectOutputStream.writeObject(properties);
			//objectOutputStream.close();
			return outputStream.toString();
		} catch (IOException e) {
			return null;
		}
	}
	
	public static String getString(String[] idCollection) {
		if(idCollection==null || idCollection.length==0){
			return "";
		}
		String data = idCollection[0];
		for (int i = 1; i < idCollection.length; i++) {
			data = data+","+idCollection[i];
		}
		return data;
	}
	
	
	public static int getCurrentDate() {
		Calendar cal = Calendar.getInstance();
		return cal.get(Calendar.DATE);
	}
	public static int getCurrentDay() {
		Calendar cal = Calendar.getInstance();
		return cal.get(Calendar.DAY_OF_WEEK);
	}
	
	/**
	 * returns converts string to int
	 * returns 0 if the given string is not a number 
	 * @param value
	 * @return int
	 */
	public static int toNumber(String value){
		try {
			return Integer.parseInt(value);
		} catch (Exception e) {
			return 0;
		}
	}
	public static int getDifferenceInDays(Date startDate, Date endDate) {
		long diffInMillisec = endDate.getTime() -  startDate.getTime();
		return (int)(diffInMillisec/MILLI_SEC_PER_DAY);
	}
	
	public static String removeIlligalChars(String value) {
		for(int i=0;i<ILLIGAL_CHARS_FILE_NAME.length;i++){
			value = value.replace(ILLIGAL_CHARS_FILE_NAME[i], '\0');
		}
		return value;
	}

	public static int getDateDifferenceMonths (Date fromDate, Date toDate) {
		int diff = 0;
		try {
			Calendar fromCal = Calendar.getInstance ();
			fromCal.setTime (fromDate);
			Calendar toCal = Calendar.getInstance ();
			toCal.setTime (toDate);

			diff = ((toCal.get(Calendar.YEAR) - fromCal.get(Calendar.YEAR)) * 12) - fromCal.get(Calendar.MONTH) + toCal.get(Calendar.MONTH);
		}
		catch (Exception e) {
			//e.printStackTrace ();
			return -1;
		}
		return diff;
	}
	
	public static int getYear(Date docDate) {
		if(docDate!=null){
			String year = format(docDate, "yyyy");
			return !Validator.isNullOrEmpty(year) ? Integer.parseInt(year) : 0;
		}
		return 0;
	}
	
	public static int getMonth(Date docDate) {
		if(docDate!=null){
			String month = format(docDate, "MM");
			return !Validator.isNullOrEmpty(month) ? Integer.parseInt(month) : 0;
		}
		return 0;
	}
	
	public static String removeLeadingZeros(String refid) {
		if(refid!=null && refid.length()>0) {
			return refid.replaceAll("^0+", "");
		}
		return refid;
	}

	public static void main(String[] args) {
		
	}

}
